iT邦幫忙

2022 iThome 鐵人賽

DAY 14
0
Modern Web

為期 N 天的 react 小冒險系列 第 14

用 react hook 寫一個 bmi 計算機-day14

  • 分享至 

  • xImage
  •  

今天來用 react hook 實作一個 bmi 計算機的小工具

分成三個元件
App.js 寫 input onChange 等邏輯的父元件
BmiRes.js 接收 身高 及 體重 這兩個 property,並計算出 bmi 值且顯示在畫面上
Input.js 輸入 身高 及 體重的欄位元件

一樣用 codesandbox 開 react 專案,import BmiRes 跟 Input
用到一個新的react hook,useReducer

import Input from "./Input.js";
import BmiRes from "./BmiRes.js";
import { useReducer } from "react";

接下來開始寫 App.js
這裡一樣會將整個 handleOnChange function 作為 props 傳到 Input (child component)
在 Input onChange 的時候執行

export default function App() {
  const [inputValues, setInputValues] = useReducer(
    (state, newState) => {
      console.log("state");
      console.log(state);
      console.log("newState");
      console.log(newState);

      return { ...state, ...newState };
    },
    { height: "", weight: "" }
  );

  const handleOnChange = (evt) => {
    // extract ext.target.value & evt.target.name from evt.target
    const { name, value } = evt.target;
    setInputValues({ [name]: value });
  };

  return (
    <div className="App">
      <h1>BMI 計算機</h1>
      <div>
        <span>身高:</span>
        <Input
          name="height"
          hint={"enter your height"}
          type={"number"}
          onChange={handleOnChange}
        />
        <br />
        <span>{inputValues.height}公分</span>
      </div>
      <div>
        <span> 體重:</span>
        <Input
          name="weight"
          hint={"enter your weight"}
          type={"number"}
          onChange={handleOnChange}
        />
        <br />
        <span>{inputValues.weight}公斤</span>
      </div>
      <BmiRes weight={inputValues.weight} height={inputValues.height} />
    </div>
  );
}

另外目前因應少量的 input 使用 useReducer
實際上如果要做表單,可以用這個 library react-form-hook
說明文件在這邊

接下來到 BmiRes.js
bmi 的公式長這樣

Math.pow( 基數 , 指數 )

import "./BmiRes.css";
const BmiRes = (props) => {
  const { weight, height } = props;
  let resultDOM = null;
  // Math.pow return base^exponent
  const res = Math.floor((weight / Math.pow(height / 100, 2)) * 100) / 100;

  res < 18.5
    ? (resultDOM = <span className="under">{res}</span>)
    : res > 18.5 && res < 24
    ? (resultDOM = <span className="normal">{res}</span>)
    : (resultDOM = <span className="over">{res}</span>);

  // under 18.5:too skinny / 18.5-24:normal / over24:overweight
  return (
    <>
      {weight && height ? (
        <p>你的BMI值為:{resultDOM}</p>
      ) : (
        <p>請輸入完整的身高及體重</p>
      )}
    </>
  );
};

export default BmiRes;

來到 Input.js
單純就 extract 出 props 並在 onChange 時執行而已

export default function Inputs(props) {
  const { hint, name, onChange, type } = props;
  return (
    <input name={name} placeholder={hint} onChange={onChange} type={type} />
  );
}

簡易的 bmi 計算器到這邊便完成了~

照慣例 codesandbox在這裡

參考資料

取到小數後兩位
https://stackoverflow.com/questions/41259253/how-to-round-down-number-2-decimal-places


上一篇
用react hook寫一個骰子遊戲吧-下-day 13
下一篇
react hook 內的快樂好朋友-useReducer-day15
系列文
為期 N 天的 react 小冒險30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言